home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CBGRX100.ARJ / EVENT.C < prev    next >
Text File  |  1992-04-10  |  7KB  |  252 lines

  1. /** 
  2.  ** EVENT.C 
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #ifndef  __TURBOC__
  25. #error     Don't even try to compile it with this compiler
  26. #endif
  27.  
  28. #pragma  inline;
  29.  
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <alloc.h>
  33. #include <stdio.h>
  34. #include <time.h>
  35. #include <dos.h>
  36.  
  37. #include "eventque.h"
  38.  
  39. extern int  far _ev_interss;    /* interrupt stack segment */
  40. extern int  far _ev_interds;    /* interrupt data segment */
  41. extern int  far _ev_kbintsp;    /* keyboard interrupt stack */
  42. extern int  far _ev_msintsp;    /* mouse interrupt stack */
  43. extern int  far _ev_kbinter;    /* keyboard interrupt flag */
  44.  
  45. extern void interrupt (* far _ev_oldkbint)(void);
  46.  
  47. extern void far          _ev_mouseint(void);
  48. extern void interrupt _ev_keybdint(void);
  49.  
  50. static void dummydraw(void) {}
  51.  
  52. static EventQueue *queue = NULL;
  53. static void (*mousedraw)(void) = dummydraw;
  54. static char *stack = NULL;
  55. static char *qsave = NULL;
  56.  
  57. static int  ms_xpos;
  58. static int  ms_ypos;
  59. static int  ms_xmickey;
  60. static int  ms_ymickey;
  61. static int  first_call = 1;
  62.  
  63. #ifdef FOR_GO32
  64. static int  my_master_pic;
  65. static int  my_new_pic;
  66. #endif
  67.  
  68. #define MS_ENABLE   EVENT_ENABLE(EVENT_MOUSE)
  69. #define KB_ENABLE   EVENT_ENABLE(EVENT_KEYBD)
  70.  
  71. #define KB_SSIZE    128        /* keyboard handler stack size */
  72. #define MS_SSIZE    128        /* mouse handler MINIMAL stack size */
  73.  
  74. #define IABS(x)        (((x) > 0) ? (x) : -(x))
  75.  
  76. void far _ev_mousehandler(int msk,int btn,int mx,int my)
  77. {
  78.     EventRecord *ep;
  79.     int moved = 0;
  80.     int diff;
  81.  
  82.     if((diff = mx - ms_xmickey) != 0) {
  83.         ms_xmickey += diff;
  84.         ms_xpos    += diff;
  85.         if((diff = ms_xpos / queue->evq_xspeed) != 0) {
  86.         ms_xpos %= queue->evq_xspeed;
  87.         if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  88.         diff += queue->evq_xpos;
  89.         if(diff <= queue->evq_xmin) diff = queue->evq_xmin;
  90.         if(diff >= queue->evq_xmax) diff = queue->evq_xmax;
  91.         if(diff != queue->evq_xpos) {
  92.             queue->evq_xpos  = diff;
  93.             queue->evq_moved = moved = 1;
  94.         }
  95.         }
  96.     }
  97.     if((diff = my - ms_ymickey) != 0) {
  98.         ms_ymickey += diff;
  99.         ms_ypos    += diff;
  100.         if((diff = ms_ypos / queue->evq_yspeed) != 0) {
  101.         ms_ypos %= queue->evq_yspeed;
  102.         if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  103.         diff += queue->evq_ypos;
  104.         if(diff <= queue->evq_ymin) diff = queue->evq_ymin;
  105.         if(diff >= queue->evq_ymax) diff = queue->evq_ymax;
  106.         if(diff != queue->evq_ypos) {
  107.             queue->evq_ypos  = diff;
  108.             queue->evq_moved = moved = 1;
  109.         }
  110.         }
  111.     }
  112.     if((msk & ~1) && (queue->evq_enable & MS_ENABLE)) {
  113.         disable();
  114.         ep = &queue->evq_events[queue->evq_wrptr];
  115.         if(++queue->evq_wrptr == queue->evq_maxsize)
  116.         queue->evq_wrptr = 0;
  117.         if(queue->evq_cursize < queue->evq_maxsize)
  118.         queue->evq_cursize++;
  119.         else if(++queue->evq_rdptr == queue->evq_maxsize)
  120.         queue->evq_rdptr = 0;
  121.         enable();
  122.         _AX = 0x200;
  123.         geninterrupt(0x16);
  124.         ep->evt_kbstat = _AL;
  125.         ep->evt_type   = EVENT_MOUSE;
  126.         ep->evt_mask   = msk;
  127.         ep->evt_button = btn;
  128.         ep->evt_xpos   = queue->evq_xpos;
  129.         ep->evt_ypos   = queue->evq_ypos;
  130.         ep->evt_time   = clock();
  131.     }
  132.     if(moved && queue->evq_drawmouse) (*mousedraw)();
  133. }
  134.  
  135. void far _ev_keybdhandler(void)
  136. {
  137.     EventRecord *ep;
  138.     int keycode;
  139.  
  140.     if(queue->evq_enable & KB_ENABLE) for( ; ; ) {
  141.         _AX = 0x100;
  142.         geninterrupt(0x16);
  143.         asm jnz  charpresent;
  144.         return;
  145.       charpresent:
  146.         keycode = (_AL != 0) ? _AL : _AH + 0x100;
  147.         if(queue->evq_delchar) {
  148.         _AX = 0;
  149.         geninterrupt(0x16);
  150.         }
  151.         disable();
  152.         ep = &queue->evq_events[queue->evq_wrptr];
  153.         if(++queue->evq_wrptr == queue->evq_maxsize)
  154.         queue->evq_wrptr = 0;
  155.         if(queue->evq_cursize < queue->evq_maxsize)
  156.         queue->evq_cursize++;
  157.         else if(++queue->evq_rdptr == queue->evq_maxsize)
  158.         queue->evq_rdptr = 0;
  159.         enable();
  160.         _AX = 0x200;
  161.         geninterrupt(0x16);
  162.         ep->evt_kbstat  = _AL;
  163.         ep->evt_keycode = keycode;
  164.         ep->evt_type    = EVENT_KEYBD;
  165.         ep->evt_time    = clock();
  166.     }
  167. }
  168.  
  169. void EventQueueDeInit(void)
  170. {
  171.     if(stack != NULL) {
  172.         _AX = 0;
  173.         geninterrupt(0x33);
  174. #ifdef FOR_GO32
  175.         setvect(my_master_pic+1,_ev_oldkbint);
  176.         if(my_new_pic != my_master_pic) setvect(my_new_pic+1,_ev_oldkbint);
  177. #else
  178.         setvect(9,_ev_oldkbint);
  179. #endif
  180.         free(stack);
  181.         free(qsave);
  182.         stack = NULL;
  183.     }
  184. }
  185.  
  186. #ifdef FOR_GO32
  187. EventQueue *EventQueueInit
  188.   (int qsize,int ms_stksize,void (*msdraw)(void),int master_pic,int new_pic)
  189. #else
  190. EventQueue *EventQueueInit(int qsize,int ms_stksize,void (*msdraw)(void))
  191. #endif
  192. {
  193.     if(stack != NULL) EventQueueDeInit();
  194.     if(qsize < 20) qsize = 20;
  195.     if(ms_stksize < MS_SSIZE) ms_stksize = MS_SSIZE;
  196.     stack = malloc(KB_SSIZE + ms_stksize);
  197.     qsave = malloc(sizeof(EventQueue)+(sizeof(EventRecord)*(qsize-1))+4);
  198.     if((stack == NULL) || (qsave == NULL)) {
  199.         if(stack != NULL) { free(stack); stack = NULL; }
  200.         if(qsave != NULL) { free(qsave); qsave = NULL; }
  201.         return(NULL);
  202.     }
  203.     _ev_interds = FP_SEG(&ms_xpos);
  204.     _ev_interss = FP_SEG(stack);
  205.     _ev_kbintsp = FP_OFF(stack) + KB_SSIZE;
  206.     _ev_msintsp = FP_OFF(stack) + KB_SSIZE + ms_stksize;
  207.     _ev_kbinter = (-1);
  208.     ms_xpos = ms_xmickey = 0;
  209.     ms_ypos = ms_ymickey = 0;
  210.     queue = (EventQueue *)(((long)qsave + 3L) & ~3L);
  211.     memset(queue,0,sizeof(EventQueue));
  212.     queue->evq_maxsize   = qsize;
  213.     queue->evq_xmax         = 79;
  214.     queue->evq_ymax         = 24;
  215.     queue->evq_xspeed    = 8;
  216.     queue->evq_yspeed    = 16;
  217.     queue->evq_thresh    = 100;
  218.     queue->evq_accel     = 1;
  219.     queue->evq_delchar   = 1;
  220.     queue->evq_enable    = MS_ENABLE | KB_ENABLE;
  221.     _AX = 0;
  222.     geninterrupt(0x33);
  223.     if(_AX != 0) {
  224.         _AX = 11;
  225.         geninterrupt(0x33);
  226.         mousedraw = (msdraw != NULL) ? msdraw : dummydraw;
  227.         _ES = FP_SEG(_ev_mouseint);
  228.         _DX = FP_OFF(_ev_mouseint);
  229.         _CX = 0xff;
  230.         _AX = 0x0c;
  231.         geninterrupt(0x33);
  232.     }
  233. #ifdef FOR_GO32
  234.     _ev_oldkbint = getvect(master_pic+1);
  235.     setvect(master_pic+1,_ev_keybdint);
  236.     if(new_pic != master_pic) setvect(new_pic+1,_ev_keybdint);
  237. #else
  238.     _ev_oldkbint = getvect(9);
  239.     setvect(9,_ev_keybdint);
  240. #endif
  241.     if(first_call) {
  242. #ifdef FOR_GO32
  243.         my_master_pic = master_pic;
  244.         my_new_pic = new_pic;
  245. #endif
  246.         atexit(EventQueueDeInit);
  247.         first_call = 0;
  248.     }
  249.     return(queue);
  250. }
  251.  
  252.